/**
 * @brief	软定时器
 * @details	无
 * @par History:
 *	v1.7: 蔡正祥, 2024-03-24, 链表结构....\n
 *	v1.7: 蔡正祥, 2024-03-29, 修改了链表的初始化....\n
 *	v1.8: 蔡正祥, 2024-04-06, 增加Ti_obj_Get_Count....\n
 *	v1.9: 蔡正祥, 2024-04-23, 将malloc()去除，恢复数组结构\n
 */
#include "bsp_Timer.h"
#include "stdlib.h"

uint32_t msValueIRQ = 0; // 非阻塞延时 ms
uint8_t msValueIRQ_Flag; // 延时标志 ms

__weak void Ti_RUN_LED_event(void)
{
    // 添加需要执行的程序
    // printf("hedddd\n");

    LED_RUN_TOGG;
}

bsp_TIM_t *TIM_Buff[TIM_TASK_MAX] = {0};
/*  @brief  定时中断函数
    @return 无
    @property 放在1ms定时器中
*/
void bsp_Ti_IRQHandler(void)
{
    for (uint8_t counti = 0; counti < TIM_TASK_MAX; counti++)
    {
        if (TIM_Buff[counti] == NULL)
        {
            break;
        }

        Ti_obj_Activate(TIM_Buff[counti]);
    }

    if (msValueIRQ_Flag == 1)
    {
        if (msValueIRQ > 0)
            msValueIRQ--;
    }
}
/*  @brief  定时任务处理函数
    @return 无
    @property 放在主循环中
*/
void bsp_Ti_All_Handle(void)
{
    static uint8_t Tim_Task_Run_Index = 0;

    for (uint8_t counti = 0; counti < 3; counti++)
    {
        if (TIM_Buff[Tim_Task_Run_Index] != NULL)
        {
            if (TIM_Buff[Tim_Task_Run_Index]->State == Ti_RUN)
            {
                Ti_obj_Handle(TIM_Buff[Tim_Task_Run_Index]);
                Tim_Task_Run_Index++;
                return;
            }
            else
            {
                Tim_Task_Run_Index++;
            }
        }
        else
        {
            Tim_Task_Run_Index = 0;
        }
    }
}
bsp_TIM_t Ti_RUN_LED11;
/*  @brief  定时任务调试程序
    @return 无
    @property 调试时用
*/
void bsp_Ti_Debug(void)
{
    Ti_obj_New(&Ti_RUN_LED11, 500, Ti_RUN, Ti_RUN_LED_event);

    while (1)
    {
        bsp_Ti_All_Handle();
    }
}

/*  @brief  设置延时时间
    @param  msValue
            延时时间ms
    @return 无
    @property 无
*/
void bsp_Ti_Set_mDelay(uint32_t msValue)
{
    msValueIRQ = msValue;
    msValueIRQ_Flag = 1;
}
/*  @brief  获取延时时间
    @return 无
    @property 无
*/
uint32_t bsp_Ti_Get_mDelay(void)
{
    return msValueIRQ;
}
/*  @brief  暂停延时
    @return 无
    @property 无
*/
void bsp_Ti_Set_mDelay_Pause(void)
{
    msValueIRQ_Flag = 0;
}
/*  @brief  恢复延时
    @return 无
    @property 无
*/
void bsp_Ti_Set_mDelay_Renew(void)
{
    msValueIRQ_Flag = 1;
}

/****************************************************************************************************************
***************************************      禁      止      修     改  ****************************************
****************************************************************************************************************/
/*  @brief  新建一个定时器对象
    @param  cycle
            定时周期
    @param  en
            是否运行    Ti_RUN运行 Ti_STOP停止
    @param  void (*event)(void)
            需要 定时执行的函数
    @return 无
    @property 无
*/
uint8_t Ti_obj_New(bsp_TIM_t *obj, uint16_t cycle, Ti_State en, void (*function)(void))
{
    obj->Cycle = cycle;
    obj->State = en;
    obj->event = function;

    for (uint8_t counti = 0; counti < TIM_TASK_MAX; counti++)
    {
        if (TIM_Buff[counti] == NULL)
        {
            TIM_Buff[counti] = obj;
            return 1;
        }
    }
    return 0;
}
/*  @brief  销毁定时器对象
    @param  *obj
            要销毁的定时器
    @return 无
    @property 无
*/
void Ti_Obj_Destroy(bsp_TIM_t *obj)
{
    uint8_t index = 0;
    for (uint8_t counti = 0; counti < TIM_TASK_MAX; counti++) // 找索引
    {
        if (TIM_Buff[counti] == obj)
        {
            index = counti;
        }
    }

    // 将后面的元素向前移动一位
    for (int countj = index; countj < TIM_TASK_MAX - 1; countj++)
    {
        TIM_Buff[countj] = TIM_Buff[countj + 1];
    }
    TIM_Buff[TIM_TASK_MAX - 1] = NULL;
}
/*  @brief  定时器对象激活
    @param  *obj
            定时器对象
    @return 无
    @property 放在定时器1ms中断中
*/
void Ti_obj_Activate(bsp_TIM_t *obj)
{
    if (obj->State == Ti_RUN) // 如果是在恢复状态 (默认是暂停状态)
    {
        obj->nowTimer++;
    }
}
/*  @brief  定时器对象处理函数
    @param  obj
            对象
    @return 无
    @property 无
*/
void Ti_obj_Handle(bsp_TIM_t *obj)
{
    if (obj->State == Ti_RUN) // 如果是在恢复状态 (默认是暂停状态)
    {
        // obj->nowTimer++;//放在定时器中++
        if (obj->nowTimer - obj->agoTimer >= obj->Cycle)
        {
            if (obj->RepeatCount > 0) // 执行固定次数
            {
                obj->LeftCount--; // 执行次数-1
                if (obj->LeftCount == 0)
                {
                    obj->State = Ti_STOP; // 暂停运行
                }
            }
            obj->event(); // 需要定时执行的任务
            obj->agoTimer = obj->nowTimer;
            if ((0xFFFFFFFF - obj->Cycle) <= obj->agoTimer) // 防止时间溢出
            {
                obj->agoTimer = obj->nowTimer = 0;
            }
        }
    }
}
/*  @brief  定时器对象 停止
    @param  *obj
            对象
    @return 无
    @property 无
*/
void Ti_obj_Set_Stop(bsp_TIM_t *obj)
{
    obj->State = Ti_STOP;
}
/*  @brief  定时器对象 运行
    @param  *obj
            对象
    @return 无
    @property 无
*/
void Ti_obj_Set_Run(bsp_TIM_t *obj)
{
    obj->State = Ti_RUN;
}
/*  @brief  定时器对象 重置
    @param  *obj
            对象
    @return 无
    @property 无
*/
void Ti_obj_Set_Reset(bsp_TIM_t *obj)
{
    obj->State = Ti_RESET;
    obj->nowTimer = 0;
    obj->agoTimer = 0;
    obj->LeftCount = obj->RepeatCount;
    obj->State = Ti_RUN;
}
/*  @brief  设置目标定时器对象的重复 次数
    @param  *obj
            对象
    @param  value
            需要重复的值
    @return 无
    @property 不设置默认无限循环
*/
void Ti_obj_Set_Count(bsp_TIM_t *obj, uint16_t value)
{
    obj->RepeatCount = value;
    obj->LeftCount = obj->RepeatCount;
}
/*  @brief  获取目标定时器对象的剩余次数
    @param  *obj
            对象
    @return 运行剩余次数
    @property 无
*/
uint16_t Ti_obj_Get_Count(bsp_TIM_t *obj)
{
    return (obj->LeftCount);
}
/*  @brief  重新设置定时器对象的 周期
    @param  *obj
            对象
    @param  value
            值 单位ms
    @return 无
    @property 定时器在创建时有个周期，通过这个函数可以更改周期
*/
void Ti_obj_Set_Cycle(bsp_TIM_t *obj, uint16_t value)
{
    obj->Cycle = value;
}
/*  @brief  设置定时对象的 事件
    @param  *obj
            对象
    @param  void (*event)(void)
            需要定时执行的事件
    @return 无
    @property 无
*/
void Ti_obj_Set_event(bsp_TIM_t *obj, void (*event)(void))
{
    obj->event = event;
}
/*  @brief  获取定时器对象运行状态
    @param  *obj
            定时器对象
    @return 无
    @property 无
*/
Ti_State Ti_obj_Get_State(bsp_TIM_t *obj)
{
    return (obj->State);
}
/****************************************************************************************************************
***************************************      禁      止      修     改  ****************************************
****************************************************************************************************************/
